#include "server.h"
#include "ui_server.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>
#include <databasetask.h>
#include <QThreadPool>
#include <QJsonArray>
#include <QMetaObject>

Server::Server(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Server)
{
    // 确保 TCP 服务器在主线程中创建
    tcpServer = new QTcpServer(this);
//    tcpServer->moveToThread(QApplication::instance()->thread());
    connect(tcpServer, &QTcpServer::newConnection,
            this, &Server::handleNewConnection,
            Qt::QueuedConnection);
}

bool Server::startServer(quint16 port)
{
    if(!tcpServer->listen(QHostAddress::Any, port)) {
        qDebug() << "Server failed to start. Error:" << tcpServer->errorString();
        return false;
    }
    qDebug() << "Server is listening on port" << port;
    return true;
}

void Server::handleNewConnection()
{
    QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
    if (!clientSocket) return;
    // 将新连接添加到 clients map 中
    clients[clientSocket] = clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
            this, &Server::handleClientData,
            Qt::QueuedConnection);
    connect(clientSocket, &QTcpSocket::disconnected,
            this, &Server::handleClientDisconnected,
            Qt::QueuedConnection);

    qDebug() << "New client connected from:" << clientSocket->peerAddress().toString();
     qDebug() << "Total connected clients:" << clients.size();
}

void Server::handleClientData()
{
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket) return;

    QByteArray data = clientSocket->readAll();
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull()) {
        qDebug() << "Failed to parse JSON data";
        return;
    }

    QJsonObject jsonObj = doc.object();
    QString type = jsonObj["type"].toString();
    qDebug()<<type<<endl;
    // 使用 map 存储不同类型的处理函数
    static const QMap<QString, std::function<void(QTcpSocket*, const QJsonObject&)>> handlers = {
        {"登录", [this](QTcpSocket*socket,const QJsonObject&json) { handleLogin(socket, json); }},
        {"注册", [this](QTcpSocket*socket,const QJsonObject&json) { handleRegister(socket, json); }},
        {"查询预约", [this](QTcpSocket*socket,const QJsonObject&json) { handleQueryAppointment(socket, json); }},
        {"创建预约", [this](QTcpSocket*socket,const QJsonObject&json) { handleCreateAppointment(socket, json); }}
    };

    // 查找并执行对应的处理函数
    auto it = handlers.find(type);
    if (it != handlers.end()) {
        it.value()(clientSocket, jsonObj);
    } else {
        qDebug() << "Unknown message type:" << type;
        QJsonObject response;
        response["result"] = "error";
        response["message"] = "Unknown message type";
        sendToClient(clientSocket, response);
    }
}
// 处理登录请求
void Server::handleLogin(QTcpSocket* clientSocket, const QJsonObject& json)
{
    QString tms_user = json["tms_user"].toString();
    QString tms_password = json["tms_password"].toString();
    QString tms_gg = json["tms_gg"].toString();
    QString sql = json["sql"].toString();

    QVariantMap params = {
        {"tms_gg", tms_gg},
        {"tms_user", tms_user},
        {"tms_password", tms_password}
    };
    executeDatabaseTask(clientSocket, sql, params, "登录");
}

// 处理注册请求
void Server::handleRegister(QTcpSocket* clientSocket, const QJsonObject& json)
{
    // 提取注册相关参数
    QString username = json["tms_user"].toString();
    QString password = json["tms_password"].toString();
    QString gg = json["tms_gg"].toString();
    QString sql = json["sql"].toString();
    QString type = json["type"].toString();
    qDebug()<<sql<<endl;
    QVariantMap params = {
        {"tms_user", username},
        {"tms_password", password},
        {"tms_gg", gg}
    };

    executeDatabaseTask(clientSocket, sql, params, type);
}

void Server::handleClientDisconnected()
{
    QTcpSocket* clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket) return;

    // 从 clients 映射中移除断开连接的客户端
     clients.remove(clientSocket);

    // 输出日志信息
    qDebug() << "Client disconnected:" << clientSocket->peerAddress().toString() << ":" << clientSocket->peerPort();

    // 如有需要,可以执行其他清理操作,如关闭客户端连接等
    clientSocket->deleteLater();
}

// 处理查询预约请求
void Server::handleQueryAppointment(QTcpSocket* clientSocket, const QJsonObject& json)
{
    QString patientId = json["patient_id"].toString();
    QString sql = json["sql"].toString();

    QVariantMap params = {
        {"patient_id", patientId}
    };

    executeDatabaseTask(clientSocket, sql, params, "查询预约");
}

// 处理创建预约请求
void Server::handleCreateAppointment(QTcpSocket* clientSocket, const QJsonObject& json)
{
    // 提取预约相关参数
    QString patientId = json["patient_id"].toString();
    QString doctorId = json["doctor_id"].toString();
    QString appointmentTime = json["appointment_time"].toString();
    QString sql = json["sql"].toString();

    QVariantMap params = {
        {"patient_id", patientId},
        {"doctor_id", doctorId},
        {"appointment_time", appointmentTime}
    };

    executeDatabaseTask(clientSocket, sql, params, "创建预约");
}

// 封装数据库任务执行
void Server::executeDatabaseTask(QTcpSocket* clientSocket, const QString& sql, const QVariantMap& params, const QString& type)
{
    if (!clientSocket || clientSocket->state() != QAbstractSocket::ConnectedState) {
        qDebug() << "Invalid client socket or connection state";
        return;
    }

    DatabaseTask* task = new DatabaseTask(sql, params, type);

    connect(task, &DatabaseTask::finished, this, [=](const QStringList&results) {
        if (clientSocket->state() == QAbstractSocket::ConnectedState) {
            QJsonObject response;
            response["type"] = type + "_response";
            response["result"] = "success";
            response["data"] = QJsonArray::fromStringList(results);
            sendToClient(clientSocket, response);
        }
    }, Qt::QueuedConnection);

    connect(task, &DatabaseTask::error, this, [=](const QString&errorMessage) {
        if (clientSocket->state() == QAbstractSocket::ConnectedState) {
            QJsonObject response;
            response["type"] = type + "_response";
            response["result"] = "error";
            response["message"] = errorMessage;
            sendToClient(clientSocket, response);
        }
    }, Qt::QueuedConnection);

    QThreadPool::globalInstance()->start(task);
}

// 向单个客户端发送信息
void Server::sendToClient(QTcpSocket *client, const QJsonObject &data)
{
    if (!client) return;

    // 确保在正确的线程中发送数据
    QMetaObject::invokeMethod(client, [=]() {
        if (client->state() != QAbstractSocket::ConnectedState) {
            qDebug() << "Client not connected";
            return;
        }

        QJsonDocument doc(data);
        QByteArray jsonData = doc.toJson();
        qint64 bytesWritten = client->write(jsonData);
        if (bytesWritten == -1) {
            qDebug() << "Failed to send data to client:" << client->errorString();
        } else {
            client->flush();
            qDebug() << "Successfully sent" << bytesWritten << "bytes to client";
        }
    }, Qt::QueuedConnection);
}

// 向所有连接的客户端广播消息
void Server::broadcastMessage(const QJsonObject &data)
{
    // 遍历所有连接的客户端
    for (QTcpSocket* client : clients.keys()) {
        sendToClient(client, data);
    }
}
